<?php
/**
 * *********************************************************************************************************************
 * 热敏单（电子面单 Thermal paper）
 * *********************************************************************************************************************
 */

namespace soa\parter\sto;
use artisan\http;
use artisan\db;
use soa\partner\partnerCommon;//热敏单公用方法（电子面单公用方法）
use soa\check\EnvCheck;//检测环境是否为线上环境

class thermalPaper
{
    /**
     * 申通电子面单接口服务地址
     * @var string
     */
    //正式地址
//    protected $service_url = '';
    protected $service_url = 'http://vip.sto.cn/PreviewInterfaceAction.action';
    //测试地址
    //protected $service_url = 'http://msdcn.f3322.net:9096/msd_vip/PreviewInterfaceAction.action';
    //protected $service_url = 'http://szdqh.wicp.net:9096/msd_vip/PreviewInterfaceAction.action';

    /**
     * erp系统签名
     * @var string
     */
    //测试签名
    //protected $data_digest = 'ec30c4dd6d04325b72688384753c2952';
    //正式环境的签名
//    protected $data_digest = '';
    protected $data_digest = 'ef73674c14451c0c9616670623c51fba';

    /**
     * 服务项目名称
     * @var string
     */
    protected $service_name = 'kuaidihelp_stovip';


    /*protected function __construct(){
        if(EnvCheck::isEnvOnline()){
            $this->data_digest = 'ef73674c14451c0c9616670623c51fba';//正式签名
            $this->service_url = 'http://vip.sto.cn/PreviewInterfaceAction.action';//正式地址
        }else{
            $this->data_digest = 'ec30c4dd6d04325b72688384753c2952';//测试签名
            $this->service_url = 'http://msdcn.f3322.net:9096/msd_vip/PreviewInterfaceAction.action';//测试地址
        }
    }*/
    /**
     * 接口错误信息配置
     * @var array
     */
    private $errorMsg = array(
        '101' => '签名不正确!',
        '104' => '没有足够的单号',
        '105' => '推送记录不能大于1000',
        '106' => '运单编号未发放,不允许录单',
        '107' => '运单编号已录单,不允许重复录入',
        '108' => '发放客户或者发放网点必须要填写',
        '109' => '请填写需要推送过来的数据',
        '110' => '撤销运单数量大于100',
        '111' => '参数有误',
        '112' => '运单撤销失败!',
        '113' => '含有无法解析字符,请检查传入的JSON数据是否正确',
        '114' => '推送数据中必须要有运单编号',
        '115' => '运单编号【xxx】,寄件日期必须要填写',
        '116' => '运单编号【xxx】,网点名称必须要填写',
        '133' => '客户密码不正确',
        '134' => '验证通过',
    );

    public function getServiceUrl()
    {
        return $this->service_url;
    }

    public function getErrorMsg($err_no)
    {
        return $this->errorMsg[$err_no] ?: '';
    }

    public function getDataDigest()
    {
        return $this->data_digest;
    }

    /**
     * 获取热敏单号
     * @param $cusname string 客户名称
     * @param $cuspwd string 客户密码
     * @param $cusite string 网点名称
     * @param $len
     * @return array|mixed|string
     */
    public function getNo($cusname, $cuspwd, $cusite, $len)
    {
        if(empty($cusname) || empty($cuspwd) || empty($cusite) || empty($len))
            return array();

        if(!is_numeric($len))
            return array();

        $result = http::post($this->getServiceUrl(), array(
            'code' => 'vip0009',
            'cusname' => $cusname,
            'cuspwd' => $cuspwd,
            'cusite' => $cusite,
            'len' => $len,
            'data_digest' => $this->getDataDigest()
        ));

        if(empty($result)) {
            return '请求超时';
        } else {
//logdebug($result,'result_sto');
            $result = json_decode($result, true);
            if(json_last_error() ==0 && $result['success'] == 'true'){
                return empty($result['data']) ? array() : explode(',', $result['data']);
            }elseif (isset($result['message'])){
                return $this->getErrorMsg($result['message']);
            }else{
logDebug($result,'stoNoJsonDecodeError');
                return '数据解析失败';
            }
        }
    }

    /**
     * 获取大字
     * @param $cuspwd
     * @param $receiveprovince
     * @param $receivecity
     * @param $receivearea
     * @return array|string
     */
    public function getCharacters($cuspwd, $receiveprovince, $receivecity, $receivearea)
    {
        if(empty($cuspwd) || empty($receiveprovince) || empty($receivecity) || empty($receivearea))
            return array();

        $result = http::post($this->getServiceUrl(), array(
            'code' => 'vip0008',
            'cuspwd' => $cuspwd,
            'receiveprovince' => $receiveprovince,
            'receivecity' => $receivecity,
            'receivearea' => $receivecity,
            'data_digest' => $this->getDataDigest()
        ));

        if(empty($result)) {
            return '请求超时';
        } else {
            $result = json_decode($result, true);
            if(json_last_error() ==0 && $result['success'] == 'true')
                return empty($result['data']) ? array() : array($result['data']);
            elseif (isset($result['message']))
                return $this->getErrorMsg($result['message']);
            else
                return '数据解析失败';
        }
    }

    /**
     * 提交电子面单数据
     * @param $cuspwd
     * @param array $datas 必须是2维数组
     *  array (
     *      array (
     *          'billno',
     *          'senddate'
     *             ...
     *      ),
     *      array(
     *          'billno',
     *          'senddate'
     *          ...
     *      )
     * )
     * @return array|string
     */
/*
    public function send1($cuspwd, array $datas)
    {
        if(empty($cuspwd) || empty($datas) || !is_array($datas))
            return array();
//logdebug($datas,'thermalPaper_sto');
        //必填的字段
        $field = array('billno', 'senddate', 'sendsite', 'sendcus', 'sendperson', 'sendtel', 'receiveperson', 'receivetel',
            'goodsname', 'inputdate', 'inputperson', 'inputsite', 'receiveprovince', 'receivecity', 'receivearea', 'receiveaddress',
            'sendprovince', 'sendcity', 'sendarea', 'sendaddress',
            );
        //非必填的字段
        $extra = array('receivecus', 'lasteditdate', 'lasteditperson', 'lasteditsite', 'remark', 'weight', 'productcode',
            'sendpcode', 'sendccode', 'sendacode', 'receivepcode', 'receiveccode', 'receiveacode', 'bigchar', 'orderno',
            );

        $need = array();
        $datasNew = array();

        foreach ($datas as $data) {
            $tmp = array();
            foreach ($field as $item) {
                if(empty($data[$item])) {
                    $need[] =  $item;
                } else {
                    $tmp[$item] = $data[$item];
                }
            }

            foreach ($extra as $value) {
                $tmp[$value] = $data[$value] ?: '';
            }

            $datasNew[] =  $tmp;
        }

        if(!empty($need)) {
            return '电子面单缺少字段"' . implode(',', $need). '"数据';
        }

        $result = http::post($this->getServiceUrl(), array(
            'code' => 'vip0007',
            'cuspwd' => $cuspwd,
            'data_digest' => $this->getDataDigest(),
            'data' => json_encode($datasNew)
        ));

        if(empty($result)) {
            return '请求超时';
        } else {
            $result = json_decode($result, true);
            if(json_last_error() ==0 && $result['success'] == 'true')
                return empty($result['data']) ? array() : $result['data'];
            elseif (isset($result['message']))
                return $this->getErrorMsg($result['message']);
            else
                return '数据解析失败';
        }
    }
*/

    /**
     * 提交电子面单数据至sto接口；并且录入我司数据库
     * @param $cuspwd
     * @param array $datas 必须是2维数组
     *  array (
     *      array (
     *          'billno',
     *          'senddate'
     *             ...
     *      ),
     *      array(
     *          'billno',
     *          'senddate'
     *          ...
     *      )
     * )
     * @return array|string
     */
    public function send($cuspwd, array $datas)
    {
        if (empty($cuspwd) || empty($datas) || !is_array($datas)){
            if(!preg_match('/^7701/', $datas['0']['billno'])){
                logDebug([$cuspwd, $datas], 'order_send_stoDataCheck', '申通录单参数校验失败', true);
            }
           
             return array();
        }
//logDebug($datas,'sto_datas');
        //必填的字段
        $field = array('billno', 'senddate', 'sendsite', 'sendcus', 'sendperson', 'sendtel', 'receiveperson', 'receivetel',
            'goodsname', 'inputdate', 'inputperson', 'inputsite', 'receiveprovince', 'receivecity', 'receivearea', 'receiveaddress',
            'sendprovince', 'sendcity', 'sendarea', 'sendaddress', 'orderno', 'cm_name', 'cm_phone', 'cm_id',
        );
        //非必填的字段
        $extra = array('receivecus', 'lasteditdate', 'lasteditperson', 'lasteditsite', 'remark', 'weight', 'productcode',
            'sendpcode', 'sendccode', 'sendacode', 'receivepcode', 'receiveccode', 'receiveacode', 'bigchar',
        );

        $need = array();
        $datasNew = array();

        foreach ($datas as $data) {
            $tmp = array();
            foreach ($field as $item) {
                if (empty($data[$item])) {
                    $need[] = $item;
                } elseif ($item != 'orderno' && $item != 'cm_name' && $item != 'cm_phone' && $item != 'cm_id') {//此处只需要拼凑sto录单需要的字段，去除我们自己入数据库需要的四个字段（这四个sto接口不需要传）
                    $tmp[$item] = $data[$item];
                }
            }

            foreach ($extra as $value) {
                $tmp[$value] = $data[$value] ?: '';
            }

            $datasNew[] = $tmp;
        }

        if (!empty($need)) {
            logDebug([$cuspwd,$datas,'电子面单缺少字段"' . implode(',', $need) . '"数据'],'order_stoSend_checkfield_error',true);
            //return '电子面单缺少字段"' . implode(',', $need) . '"数据';
        }

        $getData = array(
            'code' => 'vip0007',
            'cuspwd' => $cuspwd,
            'data_digest' => $this->getDataDigest(),
            'data' => json_encode($datasNew)
        );


        $startTime = time();
        $result = http::get($this->getServiceUrl(), $getData);

        $sendData = [
            'order_number'=> $datas['0']['orderno'],//订单号
            'waybill'     => $datas['0']['billno'],//运单号
            'brand'       => 'sto',
            'result'      => is_string($result) ? $result : json_encode($result),
            'send_data'   => is_string($getData) ? $getData : json_encode($getData),
            'time_out'    => time() - $startTime,
            'send_time'   => date('Y-m-d H:i:s'),
        ];
        $r = db::connect('orders')->table('tbl_order_send_record')->insert($sendData);
        if(!$r){
            logDebug([
                'orderNumber' => $datas['0']['orderno'],//订单号
                'waybillNo'   => $datas['0']['billno'],//运单号
                'timeOut'     => time() - $startTime,
                'brand'       => 'sto',
                'result'      => $result,
                'getData'     => $getData,
            ], 'stoSendOrderInsertErrorLog');
        }

        if (empty($result)) {
//            return '请求超时';
            return [];
        } else {
            $result = json_decode($result, true);
            if (json_last_error() == 0 && $result['success'] == 'true') {
//logdebug($datas,'partner_result');

                //录单成功；将is_send字段设为1（此字段默认为0，表示还未录单成功或者未录单过）
                $where['id'] = $datas[0]['orderno'];
                $updateData['is_send'] = '1';
                $update = db::connect('orders')->table('tbl_order')->update($where,$updateData);
                if($update === false ){
                    logdebug($datas[0]['orderno'].'-'.$updateData,'updateStoOrder_isSend_false');
                }
                //更新is_send字段结束

                foreach ($datas as $data) {
                    //以下为电子面单入库操作开始
                    //需要存入orders.tbl_thermalpaper_order的数据
                    $insertData = [
                        //订单编号
                        'order_number' => $data['orderno'],
                        //快递公司
                        'brand' => 'sto',//申通
                        //网点名称
                        'branch_name' => $data['sendsite'],
                        //快递员id
                        'cm_id' => $data['cm_id'],
                        //快递员姓名
                        'cm_name' => $data['cm_name'],
                        //快递员手机号
                        'cm_phone' => $data['cm_phone'],
                        //快递单号
                        'express_number' => $data['billno'],
                        //发件人姓名
                        'sender_name' => $data['sendperson'],
                        //发件人电话
                        'sender_phone' => $data['sendtel'],
                        //发件人省
                        'sender_province' => $data['sendprovince'],
                        //发件人市
                        'sender_city' => $data['sendcity'],
                        //发件人区
                        'sender_area' => $data['sendarea'],
                        //发件人详细地址
                        'sender_address' => $data['sendaddress'],
                        //收件人姓名
                        'receiver_name' => $data['receiveperson'],
                        //收件人电话
                        'receiver_phone' => $data['receivetel'],
                        //收件人省
                        'receiver_province' => $data['receiveprovince'],
                        //收件人市
                        'receiver_city' => $data['receivecity'],
                        //收件人区
                        'receiver_area' => $data['receivearea'],
                        //收件人详细地址
                        'receiver_address' => $data['receiveaddress'],
                        //电子面单打印时间
                        'print_time' => date('Y-m-d H:i:s'),
                        //物品类型(非必填)
                        'goods_type' => empty($data['goodsname']) ? '' : $data['goodsname'],
                        //备注信息(非必填)
                        'remark' => empty($data['remark']) ? '' : $data['remark']
                    ];
//logdebug($insertData,'partner_insert_data');
                    //调用热敏单公用方法（电子面单公用方法）
                    $partnerCommonObj = new partnerCommon();
                    $insert_ret = $partnerCommonObj->saveThermalPaperOrder($insertData);
//logdebug($insert_ret,'partner_insert_result');
                    if (!$insert_ret) {//没有录入我司数据库，记录错误日志
                        logdebug($insertData, 'sto_saveThermalPaperOrder');
                    }
                    unset($insertData, $partnerCommonObj);
                    //以上为电子面单入库操作结束
                }
                return empty($result['data']) ? array() : $result['data'];
            }
            /*
            elseif (isset($result['message'])) {
                return $this->getErrorMsg($result['message']);
            } else {
                return '数据解析失败';
            }
            */
        }
    }
}
